#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Author: Sricor
# @Date: 2022-10-25

""" SchoolBasedAuth Class """
import json
import re
from re import findall

from aiohttp.abc import AbstractCookieJar
from aiohttp.cookiejar import CookieJar

from yiban.Core import BaseReq
from yiban.Core import SchoolBased

from base64 import b64encode
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5

from yiban.Core.Exception import AuthException


class SchoolBasedAuth:
    def __init__(self, mobile: str, password: str, access_token) -> None:
        self.req = BaseReq()
        self.user_info = {}
        self.mobile = mobile
        self.password = password
        self.access_token = access_token

        # Set auth requests headers and cookies
        self.req.session.headers.update(SchoolBased.headers())

        self.add_dict_to_cookiejar(self.req.session.cookie_jar, SchoolBased.cookies())

    async def _re_auth(self, verify: str) -> None:
        client_id = "95626fa3080300ea"
        redirect_uri = "https://f.yiban.cn/iapp7463"

        response = await self.req.get(
            url="https://api.uyiban.com/base/c/auth/yiban",
            params={"verifyRequest": verify, "CSRF": SchoolBased.csrf()},
        )

        response = await self.req.get(
            url="https://oauth.yiban.cn/code/html",
            params={"client_id": client_id, "redirect_uri": redirect_uri},
        )

        # 使用正则表达式提取 page_use
        html_content = await response.text()
        pattern = r"var page_use\s*=\s*'([^']+)'"
        match = re.search(pattern, html_content)

        if match:
            page_use_value = match.group(1)
        else:
            page_use_value = ""

        response = await self.req.post(
            url="https://oauth.yiban.cn/code/usersure",
            data={"client_id": client_id,
                  "redirect_uri": redirect_uri,
                  "oauth_upwd": "false"
                  },
            params={"ajax_sign": page_use_value}
        )
        return

    async def _auth(self) -> BaseReq:
        "https://f.yiban.cn/iapp/index"
        "https://f.yiban.cn/iframe/index"

        # login_res = self.req.get(
        #     url='https://www.yiban.cn/login'
        # )
        # rsa_key = login_res.text.split("data-keys='")[1].split("'")[0]
        # key_time = login_res.text.split("data-keys-time='")[1].split("'")[0]
        # login_data = {
        #     'account' : self.mobile,
        #     'password' : self.encrypt_rsa(self.password, rsa_key),
        #     # 'captcha' : None,
        #     'keysTime' : key_time,
        #     # 'rid': ''
        #     # 'redirect_uri' : 'https://f.yiban.cn/iapp7463'
        # }
        # # TODO 验证码
        # login_res = self.req.post(
        #     url="https://www.yiban.cn/login/doLoginAjax",
        #     headers={

        #     },
        #     data=login_data
        # )

        response = await self.req.get(
            url="https://f.yiban.cn/iapp/index",
            params={"act": "iapp7463"},
            headers={
                "authorization": "Bearer " + self.access_token,
                'logintoken': self.access_token,
            },
            allow_redirects=False,
        )

        location = response.headers.get("Location")
        if location is None:
            await self.req.session.close() # 关闭失效的Req
            raise AuthException(f'校本化认证失败: {await response.text()}')
        verify = findall(r"verify_request=(.*?)&", location)[0]

        # re auth
        await self._re_auth(verify)

        response_str = await (await self.req.get(
            url="https://api.uyiban.com/base/c/auth/yiban",
            params={"verifyRequest": verify, "CSRF": SchoolBased.csrf()},
            allow_redirects=True,
        )).text()
        try:
            response = json.loads(response_str)
        except json.decoder.JSONDecodeError:
            raise

        # if auth done return requests class else raise
        if response["code"] == 0:
            self.user_info = response["data"]
            return self.req
        else:
            raise Exception(f"Auth Error {response['msg']}")

    def _get_name(self) -> str:
        return self.user_info["PersonName"]

    @staticmethod
    def encrypt_rsa(data: str, rsa_key: str) -> str:
        """
        登录密码加密
        :param data: （必须）待加密密码
        :return: Any
        """
        data_bytes = bytes(data, encoding="utf8")
        encrypt = PKCS1_v1_5.new(RSA.importKey(rsa_key))
        sencrypt = b64encode(encrypt.encrypt(data_bytes))
        return sencrypt.decode("utf-8")


    @staticmethod
    def add_dict_to_cookiejar(cookie_jar: AbstractCookieJar, data: dict):
        # 将 Cookie 添加到 Session 的 CookieJar 中
        cookie_jar.update_cookies(data)


"""
{
'code': 0, 
'msg': '', 
'data': {
    'UniversityName': '', 
    'UniversityId': '', 
    'PersonId': '', 
    'PersonName': '', 
    'State': 1, 
    'PersonType': 'student', 
    'UniversityIcon': '', 
    'Container': 'StudentDefault', 
    'HomeTheme': 'HomeDefault', 
    'CustomApps': {
        'up': [], 
        'down': []}, 
        'Group': [], 
        'Apps': [
            {
                'Id': '', 
                'ServiceId': '', 
                'AppIcon': '', 
                'AppUrl': '', 
                'AppRuleUrl': '', 
                'AuthCode': '', 
                'AppName': ''
            }
        ], 
        'WxState': 0, 
        'DingDingState': 0
    }
}
"""
